home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 15
/
Aminet 15 - Nov 1996.iso
/
Aminet
/
dev
/
lang
/
FPL_v147.lha
/
fpl
/
funclib
/
lib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-22
|
6KB
|
224 lines
/********************************************************************
*
* This is a funclib program example. It is run from the from the
* "func" program example. It is started with a simple run and
* stopped when it receives a break-signal.
*
* This program can be made pure/re-entrant.
*
*/
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/fpl.h>
#include <libraries/fpl.h>
#include <exec/execbase.h>
#include <exec/ports.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "funclib.h"
#define TEMPLATE "Version/N/A,Anchor/N/A"
#define OURTASKNAME "FPLlib"
#define OTHERTASKNAME "FPLfunc"
enum {
opt_VERSION,
opt_ANCHOR,
opt_COUNT,
};
struct ReportMsg {
struct Message msg;
int ErrorNumber;
};
extern struct ExecBase *SysBase;
struct Library *FPLBase=NULL;
long __asm func(register __a0 struct fplArgument *);
void CloseOurPort(struct MsgPort *port)
{
if (port){
RemPort(port);
DeleteMsgPort(port);
}
}
int main(int argc, char **argv)
{
LONG opts[opt_COUNT];
long version;
long anchor;
char ourportname[40];
char otherportname[40];
struct RDArgs *argsptr;
struct MsgPort *port;
struct MsgPort *otherport;
struct ReportMsg *receive;
int Error=0;
if (SysBase->LibNode.lib_Version > 36) {
argsptr = ReadArgs(TEMPLATE, opts, NULL);
if (argsptr) {
version = *((LONG *)opts[opt_VERSION]);
anchor = *((LONG *)opts[opt_ANCHOR]);
FreeArgs(argsptr);
} else {
PrintFault(IoErr(), NULL); /* prints the appropriate err message */
return FUNCLIB_PARAMETER;
}
} else {
char Nomatch=0;
if(argc<5)
return FUNCLIB_PARAMETER;
else {
if(!strcmp("version", argv[version=1]) ||
!strcmp("anchor", argv[anchor=3]))
Nomatch=TRUE;
else if(!strcmp("version", argv[version=3]) ||
!strcmp("anchor", argv[anchor=1]))
Nomatch=TRUE;
if(Nomatch)
return FUNCLIB_PARAMETER;
version=atoi(argv[version]);
anchor=atoi(argv[anchor]);
}
}
sprintf(ourportname, "%s.%d", OURTASKNAME, anchor);
sprintf(otherportname, "%s.%d", OTHERTASKNAME, anchor);
/* Make our port, so that our father can find us */
if (port=CreateMsgPort()){
port->mp_Node.ln_Name=ourportname;
port->mp_Node.ln_Pri=0;
AddPort(port);
} else
return FUNCLIB_INTERNAL; /* We failed... */
/*
* Here should the funclib perform its initializations.
*/
/*
* We check that the anchor is above 400 to prevent test
* runnings to actually try to add functions to a non-existant
* anchor.
*/
if(anchor > 400) {
/* open fpl.library */
FPLBase = OpenLibrary("fpl.library", 6);
if(!FPLBase) {
CloseOurPort(port);
return FUNCLIB_RESOURCE;
} else {
fplAddFunctionTags((void *)anchor, "libTest", 1, 'S', NULL,
FPLTAG_FUNCTION, func, FPLTAG_DONE);
fplAddFunctionTags((void *)anchor, "libTest2", 2, 'I', NULL,
FPLTAG_FUNCTION, func, FPLTAG_DONE);
}
}
/* Tell papa we have initialized and are ready to be used! */
Forbid();
if (otherport = FindPort(otherportname)) {
struct ReportMsg Iamup;
Iamup.msg.mn_ReplyPort=port;
Iamup.ErrorNumber=Error;
PutMsg(otherport,&Iamup.msg);
Permit();
/* Check if we have had any errors */
if (!Error) {
/* Now let's wait for our reply */
WaitPort(port);
GetMsg(port);
/* Now Iamup.ErrorNumber could be read to check for information */
/* We wait here until they tell us to close down the funclib. */
WaitPort(port);
/* (No reply before we have finished things up ...) */
} else { /* We had an error. No reply will come. Finnish up */
/* Wait for 5 seconds, so that we are sure the message has been received */
Delay(50*5);
CloseOurPort(port);
CloseLibrary(FPLBase);
/* Return to nowhere */
return FUNCLIB_INTERNAL;
}
} else { /*
* No fatherport. This error SHOULD not be able to happen !
* since our father would not have started us if it failed
* opening that port
*/
Permit();
CloseOurPort(port);
CloseLibrary(FPLBase);
return FUNCLIB_INTERNAL;
}
/* here are all the closing down functions performed. */
/*
* We check that the anchor is above 400 to prevent test
* runnings to actually try to delete functions with a non-existant
* anchor.
*/
if (anchor > 400 && otherport) {
/* remove our test functions */
fplDelFunction((void *)anchor, "libTest");
fplDelFunction((void *)anchor, "libTest2");
/* close library */
CloseLibrary(FPLBase);
}
/* tell our controller that we are about to die! */
receive=(struct ReportMsg *) GetMsg(port);
/* We could use the receive.ErrorNumber field to check for special commandos */
/* We also could write the errorfield to notify our father
if we had any errors */
ReplyMsg((struct Message *) receive);
/*
* Right after we send that reply to our controlling process, that
* process will consider us done and continue. We do our best by
* exiting silently but have no longer any speed demands...
*/
/*
* We close our port.
*/
CloseOurPort(port);
/*
* Returning to nowhere...
*/
return FUNCLIB_OK;
}
long __asm __saveds func(register __a0 struct fplArgument *arg)
{
/*
* Here are all our functions!
*/
switch(arg->ID) {
case 1:
fplSendTags(arg->key, FPLSEND_STRING, "testlibstring", FPLTAG_DONE);
break;
case 2:
{
char *prog = "Lazer();";
fplExecuteScript(arg->key, &prog, 1, FPLTAG_DONE);
}
break;
default:
break;
}
return FPL_OK;
}